﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using OT.Data;
using OT.Areas.Admin.Models;
using OT.Areas.Instructor.Models;
using PagedList;
using System.Web.Script.Serialization;
using Newtonsoft.Json;

namespace OT.Areas.Instructor.Controllers
{
    public class TestController : Controller
    {
        readonly OTEntitiesme OTDb = new OTEntitiesme();
        int LanguageID = Utilities.GetLanguageID();
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public JsonResult Index(int pageNumber, int pageSize, string searchString, int pgindex, string columnFilter)
        {
            var Test = (List<Tests>)null;
            int recount = 0;
            try
            {
                int UserID = 0;
                if (Request.Cookies["LoginSesID"] != null)
                {
                    UserID = Convert.ToInt16(Request.Cookies["LoginSesID"].Value); ;
                }
                else
                {
                    TempData["notice"] = "Time Out ,Please Login";
                    Response.Redirect("~/Home");
                }
                Test = (from c in OTDb.Tests
                        join ttyp in OTDb.TestTypes
                       on c.TestTypeID equals ttyp.TestTypeID into output
                        join top in OTDb.Topics
                         on c.TopicID equals top.TopicID
                        join sub in OTDb.Subjects
                       on c.SubjectID equals sub.SubjectID
                        from j in output.DefaultIfEmpty()
                        where c.UserID.Value.Equals(UserID)
                        select new Tests
                        {
                            TestID = c.TestID,
                            TestName = c.TestName,
                            Description = c.Description,
                            TotalQuestion = (int)c.TotalQuestion,
                            CategoryName = c.Category.CategoryName,
                            Duration = (int)c.Duration,
                            PassingScore = (byte)c.PassingScore,
                            PositiveMark = (byte)c.PositiveMark,
                            NegativeMark = (byte)c.NegativeMark,
                            TopicName = top.TopicName,
                            CategoryID = c.CategoryID.Value,
                            Subject = sub.SubjectName,
                            TestType1 = j.TestType1,
                            CreatedDate = (DateTime)c.CreatedDate,
                            UpdatedDate = (DateTime)c.UpdatedDate,
                            noofatmpt = OTDb.AttemptMsts.Where(a => a.TestID.Value.Equals(c.TestID)).Count<AttemptMst>()
                        }
                       ).ToList();

                if (!String.IsNullOrEmpty(searchString))
                    Test = Test.Where(r => r.TestName.ToLower().Contains(searchString.ToLower())).ToList();

                recount =Test.Count;

                Test = Test.Skip<Tests>(pgindex * (pageNumber - 1))
                    .Take<Tests>(pgindex).ToList<Tests>();

            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }

            return Json(new
            {
                PageNumber = pageNumber,
                PageSize = pageSize,
                PgIndex = pgindex,
                Data = Test,
                RecordCount = recount
            });
        }
        public ActionResult Create()
        {
            Tests Test = null;
            try
            {
                Test = new Tests();
                var tt = OTDb.TestTypes.ToList();
                Test.TestTypes = tt;
                var top = OTDb.Topics.Where(t=>t.Status==true).ToList();
                Test.Topics = top;
                var cat = OTDb.Categories.Where(c=>c.Status==true).ToList();
                Test.cat = cat;
                var Sub = OTDb.Subjects.Where(s=>s.Status==true).ToList();
                Test.Subjects = Sub;
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return PartialView(Test);
        }

        [HttpPost]
        public string Create(string TestName, int TestTypeID, int CategoryID, int SubjectID, int TopicID, string Description, int TotalQuestion, int Duration, byte PassingScore, byte PositiveMark, byte NegativeMark, bool Status, string QuestionIDs, string StudentIDs)
        {
            string result = "";
            Test Test = null;
            TestQuestion TestQuestion = null;
            TestUser user = null;
            try
            {
                if (ModelState.IsValid)
                {
                    int UserID = Convert.ToInt16(Request.Cookies["LoginSesID"].Value); ;
                    Test = new Test();
                    Test.TestName = TestName;
                    Test.Description = Description;
                    Test.TotalQuestion = TotalQuestion;
                    Test.Duration = Duration;
                    Test.PassingScore = PassingScore;
                    Test.PositiveMark = PositiveMark;
                    Test.NegativeMark = NegativeMark;
                    Test.Status = Status;
                    if (TestTypeID != 0)
                        Test.TestTypeID = TestTypeID;
                    if (SubjectID != 0)
                        Test.SubjectID = SubjectID;
                    if (TopicID != 0)
                        Test.TopicID = TopicID;
                    Test.CategoryID = CategoryID;
                    Test.SubjectID = SubjectID;
                    Test.TopicID = TopicID;
                    Test.UserID = UserID;
                    Test.CreatedDate = DateTime.Now;
                    Test.UpdatedDate = DateTime.Now;
                    Test.LanguageID = LanguageID;
                    OTDb.Tests.Add(Test);
                    OTDb.SaveChanges();
                    if (string.IsNullOrEmpty(QuestionIDs))
                    {
                        var ql = OTDb.Questions.Where(r => r.SubjectID == SubjectID && r.TopicID == TopicID).ToList();
                        int cnt = 0;
                        foreach (Question drq in ql)
                        {
                            if (cnt < TotalQuestion)
                            {
                                TestQuestion = new TestQuestion();
                                TestQuestion.QuestionID = drq.QuestionID;
                                TestQuestion.TestID = Test.TestID;
                                OTDb.TestQuestions.Add(TestQuestion);
                                OTDb.SaveChanges();
                            }
                            cnt++;
                        }
                    }
                    else
                    {
                        string[] sep = { "," };
                        string[] IDs = QuestionIDs.Split(sep, StringSplitOptions.RemoveEmptyEntries);
                        List<int> ids = new List<int>();
                        foreach (var id in IDs)
                            ids.Add(Convert.ToInt32(id));
                        foreach (int QuestionID in ids)
                        {
                            TestQuestion = new TestQuestion();
                            TestQuestion.QuestionID = QuestionID;
                            TestQuestion.TestID = Test.TestID;
                            OTDb.TestQuestions.Add(TestQuestion);
                            OTDb.SaveChanges();
                        }
                    }
                    if (!string.IsNullOrEmpty(StudentIDs))
                    {
                        string[] sep = { "," };
                        string[] IDs = StudentIDs.Split(sep, StringSplitOptions.RemoveEmptyEntries);
                        List<int> ids = new List<int>();
                        foreach (var id in IDs)
                            ids.Add(Convert.ToInt32(id));
                        foreach (int StudentID in ids)
                        {
                            user = new TestUser();
                            user.UserID = StudentID;
                            user.TestID = Test.TestID;
                            OTDb.TestUsers.Add(user);
                            OTDb.SaveChanges();
                        }
                    }
                    else
                    {
                        var us = OTDb.Users.Where(c=>c.UserTypeID==3).ToList();
                        foreach (User drq in us)
                        {
                            user = new TestUser();
                            user.UserID = drq.UserID;
                            user.TestID = Test.TestID;
                            OTDb.TestUsers.Add(user);
                            OTDb.SaveChanges();
                        }
                    }
                    result = "Success";
                }
                else
                {
                    result = "NotValid";
                }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return result;
        }

        public ActionResult ShowTestAttemptList(int TestID)
        {

            try
            {   
                var Attempts = (List<TestAttemptDetail>)null;
                try
                {
                    Attempts = (from c in OTDb.AttemptMsts
                                where c.TestID.Value.Equals(TestID)
                                join top in OTDb.Users
                                on c.UserID equals top.UserID
                                join tst in OTDb.Tests
                                on c.TestID equals tst.TestID
                                select new TestAttemptDetail
                                {
                                    TestName=tst.TestName,
                                    StudentName=top.FirstName,
                                    IsFinish=(bool)c.IsFinish,
                                    Score=(float)c.Score,
                                    DateofExam=(DateTime)c.CreatedDate
                                    
                                }).ToList();
                
                }
                catch (Exception ex)
                {
                    Utilities.InsertErrorLog(ex);
                }
                return View(Attempts.ToPagedList(1, 300));
            }
            catch (Exception e)
            {
                Utilities.InsertErrorLog(e.InnerException);
            }
            return View();
          
        }
        public ActionResult Edit(int TestID)
        {
            Tests Tests = null;
            try
            {
                var tst = OTDb.Tests.Where(r => r.TestID == TestID).SingleOrDefault();
                if (tst != null)
                {
                    Tests = new Tests();
                    Tests.TestID = tst.TestID;
                    Tests.TestName = tst.TestName;
                    Tests.Description = tst.Description;
                    Tests.totalStudent = OTDb.TestUsers.Where(c => c.TestID.Value.Equals(TestID)).Select(c => c.UserID).Count();
                    var Questionslist = OTDb.TestQuestions.Where(r => r.TestID.Value.Equals(tst.TestID)).ToList();
                    if (Questionslist != null)
                    {
                        Tests.totalAvailQue = Questionslist.Count;
                    }
                    string res = GetAvailableQuestion((int)tst.SubjectID, (int)tst.TopicID);
                    Tests.totalAvailQue = Convert.ToInt16( res);
                    Tests.Status = (bool)tst.Status;
                    if (tst.TestTypeID != null)
                        Tests.TestTypeID = (int)tst.TestTypeID;
                    if (tst.SubjectID != null)
                        Tests.SubjectID = (int)tst.SubjectID;
                    if (tst.TopicID != null)
                        Tests.TopicID = (int)tst.TopicID;
                    Tests.TotalQuestion = Questionslist.Count;
                    Tests.Duration = (int)tst.Duration;
                    Tests.PassingScore = (byte)tst.PassingScore;
                    Tests.PositiveMark = (byte)tst.PositiveMark;
                    Tests.NegativeMark = (byte)tst.NegativeMark;
                    Tests.SubjectID = (int)tst.SubjectID;
                    Tests.TopicID = (int)tst.TopicID;
                    Tests.CategoryID = tst.CategoryID.Value;
                    var top = OTDb.Topics.Where(t => t.SubjectID.Value.Equals(tst.SubjectID.Value)).ToList();
                    Tests.Topics = top;
                    var sub = OTDb.Subjects.Where(s => s.CategoryID.Value.Equals(tst.CategoryID.Value)).ToList();
                    Tests.Subjects = sub;
                    var category = OTDb.TestTypes.ToList();
                    Tests.TestTypes = category;
                    var cat = OTDb.Categories.ToList();
                    Tests.cat = cat;
                }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return PartialView(Tests);
        }

        [HttpPost]
        public string Edit(int TestID, string TestName, int TestTypeID, int CategoryID, int SubjectID, int TopicID, string Description, int TotalQuestion, int Duration, byte PassingScore, byte PositiveMark, byte NegativeMark, string QuestionIDs, string StudentIDs)
        {
            string result = "";
            TestQuestion TestQuestion = null;
            TestUser user = null;
            try
            {
                if (ModelState.IsValid)
                {
                    var category = OTDb.Tests.Where(r => r.TestID == TestID).SingleOrDefault();
                    if (category != null)
                    {
                        category.TestName = TestName;
                        category.Description = Description;
                        category.Duration = Duration;
                        category.TotalQuestion = TotalQuestion;
                        category.PassingScore = PassingScore;
                        category.PositiveMark = PositiveMark;
                        category.NegativeMark = NegativeMark;
                        category.UpdatedDate = DateTime.Now;
                        if (TestTypeID != 0)
                            category.TestTypeID = TestTypeID;
                        if (TopicID != 0)
                            category.TopicID = TopicID;
                        if (SubjectID != 0)
                            category.SubjectID = SubjectID;
                        if (string.IsNullOrEmpty(QuestionIDs))
                        {
                            var ql = OTDb.Questions.Where(r => r.SubjectID == SubjectID && r.TopicID == TopicID).ToList();
                            int cnt = 0;
                            foreach (Question drq in ql)
                            {
                                if (cnt < TotalQuestion)
                                {
                                    if (!IsTestQuestionExist(TestID, drq.QuestionID, CategoryID))
                                    {
                                        if (CategoryID != 0)
                                            category.CategoryID = CategoryID;
                                        TestQuestion = new TestQuestion();
                                        TestQuestion.QuestionID = drq.QuestionID;
                                        TestQuestion.TestID = TestID;
                                        OTDb.TestQuestions.Add(TestQuestion);
                                        OTDb.SaveChanges();
                                    }
                                }
                                cnt++;
                            }
                        }
                        else
                        {
                            string[] sep = { "," };
                            string[] IDs = QuestionIDs.Split(sep, StringSplitOptions.RemoveEmptyEntries);
                            List<int> ids = new List<int>();
                            foreach (var id in IDs)
                                ids.Add(Convert.ToInt32(id));
                            List<TestQuestion> test = OTDb.TestQuestions.Where(t => t.TestID.Value.Equals(TestID)).ToList();
                            foreach (TestQuestion tst in test)
                            {
                                OTDb.TestQuestions.Remove(tst);
                                OTDb.SaveChanges();
                            }
                            foreach (int QuestionID in ids)
                            {
                                if (CategoryID != 0)
                                    category.CategoryID = CategoryID;
                                TestQuestion = new TestQuestion();
                                TestQuestion.QuestionID = QuestionID;
                                TestQuestion.TestID = TestID;
                                OTDb.TestQuestions.Add(TestQuestion);
                                OTDb.SaveChanges();
                            }
                        }

                        if (!string.IsNullOrEmpty(StudentIDs))
                        {
                            string[] sep = { "," };
                            string[] IDs = StudentIDs.Split(sep, StringSplitOptions.RemoveEmptyEntries);
                            List<int> ids = new List<int>();
                            foreach (var id in IDs)
                                ids.Add(Convert.ToInt32(id));
                            List<TestUser> users = OTDb.TestUsers.Where(t => t.TestID.Value.Equals(TestID)).ToList();
                            if (users.Count != 0)
                            {
                                foreach (TestUser usr in users)
                                {
                                    OTDb.TestUsers.Remove(usr);
                                    OTDb.SaveChanges();
                                }
                            }
                            foreach (int StudentID in ids)
                            {
                                user = new TestUser();
                                user.UserID = StudentID;
                                user.TestID = TestID;
                                OTDb.TestUsers.Add(user);
                                OTDb.SaveChanges();
                            }
                        }
                        else
                        {
                            var us = OTDb.Users.ToList();
                            foreach (User drq in us)
                            {
                                if (!IsTestUserExist(TestID, drq.UserID))
                                {
                                    user = new TestUser();
                                    user.UserID = drq.UserID;
                                    user.TestID = TestID;
                                    OTDb.TestUsers.Add(user);
                                    OTDb.SaveChanges();
                                }
                            }
                        }
                        result = "Success";
                    }
                }
                else
                {
                    result = "NotValid";
                }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
                result = "NotValid";
            }
            return result;
        }

        public ActionResult Delete(int TestID)
        {
            Tests Tests = null;
            try
            {
                var tast = OTDb.Tests.Where(r => r.TestID == TestID).SingleOrDefault();
                if (tast != null)
                {
                    Tests = new Tests();

                    Tests.TestID = tast.TestID;
                    Tests.TestName = tast.TestName;
                    Tests.Description = tast.Description;
                    Tests.Status = (bool)tast.Status;
                    Tests.TotalQuestion = (int)tast.TotalQuestion;
                    Tests.Duration = (int)tast.Duration;
                    Tests.PassingScore = (byte)tast.PassingScore;
                    Tests.PositiveMark = (byte)tast.PositiveMark;
                    Tests.NegativeMark = (byte)tast.NegativeMark;
                    Tests.SubjectID = (int)tast.SubjectID;
                    Tests.TopicID = (int)tast.TopicID;
                    if (tast.SubjectID != null)
                        Tests.SubjectID = (int)tast.SubjectID;
                    if (tast.TopicID != null)
                        Tests.TopicID = (int)tast.TopicID;
                    if (tast.TestTypeID != null)
                        Tests.TestTypeID = (int)tast.TestTypeID;
                    var top = OTDb.Topics.ToList();
                    Tests.Topics = top;
                    var sub = OTDb.Subjects.ToList();
                    Tests.Subjects = sub;
                    var category = OTDb.TestTypes.ToList();
                    Tests.TestTypes = category;
                }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return PartialView(Tests);
        }

        [HttpPost]
        public string Delete(int TestID, string IsDelete)
        {
            string result = "";
            try
            {
                var Tst = OTDb.Tests.Where(r => r.TestID == TestID).SingleOrDefault();
                if (Tst != null)
                {
                    OTDb.Tests.Remove(Tst);
                    OTDb.SaveChanges();

                    result = "Success";
                }
                else { result = "NotValid"; }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
                result = "NotValid";
            }
            return result;
        }

        public string GetAvailableQuestion(int SubjectID, int TopicID)
        {
            string response = string.Empty;
            try
            {
                var Questionslist = OTDb.Questions.Where(r => r.SubjectID.Value == SubjectID && r.TopicID.Value == TopicID && r.Status==true).ToList();
                if (Questionslist != null)
                {
                    response = Questionslist.Count.ToString();
                }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return response;
        }

        public bool IsTestQuestionExist(int TestID, int QuestionID, int CategoryID)
        {
            bool response = false;
            try
            {
                var Questionslist = OTDb.TestQuestions.Where(r => r.TestID.Value == TestID && r.QuestionID.Value == QuestionID).ToList();
                if (Questionslist.Count != 0)
                {
                    response = true;
                }
                List<TestQuestion> TestQuestion = OTDb.TestQuestions.Where(r => r.TestID.Value == TestID).ToList();
                foreach (TestQuestion tst in TestQuestion)
                {
                    if (!tst.Test.CategoryID.Value.Equals(CategoryID))
                    {
                        OTDb.TestQuestions.Remove(tst);
                        OTDb.SaveChanges();
                    }
                }

            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return response;
        }

        public bool IsTestUserExist(int TestID, int UserID)
        {
            bool response = false;
            try
            {
                var Questionslist = OTDb.TestUsers.Where(r => r.TestID.Value == TestID && r.UserID.Value == UserID).ToList();
                if (Questionslist.Count != 0)
                {
                    response = true;
                }
                List<TestUser> users = OTDb.TestUsers.Where(t => t.TestID.Value.Equals(TestID)).ToList();

                if (users.Count != 0)
                {
                    foreach (TestUser usr in users)
                    {
                        OTDb.TestUsers.Remove(usr);
                        OTDb.SaveChanges();
                    }
                }

            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return response;
        }

        public ActionResult GetAllStudent()
        {
            var StudentList = (List<StudentList>)null;
            StudentList = (from c in OTDb.Users
                           where c.UserTypeID == 3
                           select new StudentList
                           {
                               UserID=c.UserID,
                               Name=c.FirstName +"-"+c.LastName ,
                             
                               RegistrationDate=c.CreatedDate==null?DateTime.Today:(DateTime)c.CreatedDate
                           }
                           ).ToList();

            return PartialView(StudentList.ToPagedList(1, 100000));
        }

        public JsonResult GetTestUsers(int TestID)
        {
                List<TestUsers> StudentList = (from c in OTDb.TestUsers
                                               where c.TestID.Value.Equals(TestID)
                                               select new TestUsers { UserID = c.UserID.Value, TestID = c.TestID.Value, TestUserID = c.TestUserID }).ToList();
                return Json(new
                {
                    Data = StudentList,
                });

        }

        public JsonResult GetTestQuestions(int TestID)
        {
            List<TestQuestions> QuestionList = (from c in OTDb.TestQuestions
                                                where c.TestID.Value.Equals(TestID)
                                                select new TestQuestions { QuestionID = c.QuestionID.Value, TestID = c.TestID.Value, TestQuestionID = c.TestQuestionID }).ToList();
            return Json(new
            {
                Data = QuestionList,
            });
        }

        public static List<SelctedQuestionList_Result> data1obj;
        public ActionResult ShowAllQuestion(int subjectId, int topicid,int testid)
        {
            data1obj = OTDb.SelctedQuestionList(subjectId, topicid, testid).ToList<SelctedQuestionList_Result>();
            return PartialView(data1obj.ToPagedList(1, 1000));
        }
        public ActionResult ShowAllQuestionCreate(int subjectId, int topicid)
        {
            var Questionslist = (List<Question>)null;
            Questionslist = (from c in OTDb.Questions
                             where c.SubjectID.Value.Equals(subjectId) && c.TopicID.Value.Equals(topicid) && c.Status==true
                             select c).ToList();

            return PartialView(Questionslist.ToPagedList(1, 1000));
        }
    }
}